----------------------------------------------------------------------------------
-- Company: 09T embedded
-- Engineer: THUY - LAN - TIN
-- 
-- Create Date:    19:10:59 10/14/2013 
-- Design Name: 
-- Module Name:    arbiter2 - Behavioral 
-- Project Name: Arbiter
-- Target Devices: 
-- Tool versions: ISE
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity arbiter2 is
    Port ( clk : in  STD_LOGIC;
           reset : in  STD_LOGIC;
           r : in  STD_LOGIC_VECTOR(1 DOWNTO 0);
           g : out  STD_LOGIC_VECTOR(1 DOWNTO 0));
end arbiter2;

architecture fixed_prio_arch of arbiter2 is
	type mc_state_type is (waitr, grant1, grant0);
	signal state_reg, state_next: mc_state_type;
begin
	--state register
	process(clk, reset)
	begin
		if (reset = '1') then
			state_reg <= waitr;
		elsif (clk'event and clk = '1') then
			state_reg <= state_next;
		end if;
	end process;
	
	--next state and output logic
	process (state_reg, r)
	begin
		g <= "00";
		case state_reg is
			when waitr =>
				if (r(1) = '1') then
					state_next <= grant1;
					g(1) <= '1';
				elsif (r(0) = '1') then                
					state_next <= grant0;
					g(0) <= '1';
				else
					state_next <= waitr;
				end if;
			when grant1 =>
				if r(1) = '1' then
					state_next <= grant1;
				else
					state_next <= waitr;
				end if;
				g(1) <= '1';
			when grant0 =>
				if r(1) = '1' then
					state_next <= grant0;
				else
					state_next <= waitr;
				end if;
				g(0) <= '1';
		end case;
	end process;
end fixed_prio_arch;

	
architecture rotated_prio_arch of arbiter2 is
	type mc_state_type is (waitr1, waitr0, grant1, grant0);
	signal state_reg, state_next: mc_state_type;
begin
	--state register
	process(clk, reset)
	begin
		if(reset = '1') then
			state_reg <= waitr1;
		elsif (clk'event and clk = '1') then
			state_reg <= state_next;
		end if;
	end process;
		
	--next-state and output logic
	process(state_reg, r)
	begin
		g <= "00"; --default values
		case state_reg is
			when waitr1 =>
				if (r(1) = '1') then
					state_next <= grant1;
				elsif (r(0) = '1') then
					state_next <= grant0;
				else
					state_next <= waitr1;
				end if;
			when waitr0 =>
				if( r(0) = '1') then
					state_next <= grant0;
				elsif (r(1) = '1') then
					state_next <= grant1;
				else
					state_next <= waitr0;
				end if;
			when grant1 =>
				if (r(1) = '1') then
					state_next <= grant1;
				else
					state_next <= waitr0;
				end if;
				g(1) <= '1';
			when grant0 =>
				if (r(0) = '1') then
					state_next <= grant0;
				else
					state_next <= waitr1;
				end if;
				g(0) <= '1';
		end case;
	end process;
end rotated_prio_arch;

